{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "6d3408be",
   "metadata": {},
   "source": [
    "# Ranking and Position Sizing\n",
    "\n",
    "In this notebook, we will learn about the features of **PyBroker** that enable you to rank ticker symbols and set position sizes for a group of symbols in your trading strategy. With these features, you can easily optimize your strategy and manage risk more effectively."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "54a5bef2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<diskcache.core.Cache at 0x7fd17427dd60>"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import pybroker\n",
    "from pybroker import Strategy, StrategyConfig, YFinance\n",
    "\n",
    "pybroker.enable_data_source_cache('ranking_and_pos_sizing')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "378fa91e",
   "metadata": {},
   "source": [
    "## Ranking Ticker Symbols\n",
    "\n",
    "In this section, we will learn about how to rank ticker symbols when placing buy orders. Let's begin with an example of how to rank ticker symbols based on volume when placing buy orders. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "3d0aa5e4",
   "metadata": {},
   "outputs": [],
   "source": [
    "def buy_highest_volume(ctx):\n",
    "    # If there are no long positions across all tickers being traded:\n",
    "    if not tuple(ctx.long_positions()):\n",
    "        ctx.buy_shares = ctx.calc_target_shares(1)\n",
    "        ctx.hold_bars = 2\n",
    "        ctx.score = ctx.volume[-1]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b0a70a5c",
   "metadata": {},
   "source": [
    "The ```buy_highest_volume``` function ranks ticker symbols by their most recent trading volume and allocates 100% of the portfolio for 2 bars. The ```ctx.score``` is set to ```ctx.volume[-1]```, which is the most recent trading volume."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "e82e0629",
   "metadata": {},
   "outputs": [],
   "source": [
    "config = StrategyConfig(max_long_positions=1)\n",
    "strategy = Strategy(YFinance(), '6/1/2021', '6/1/2022', config)\n",
    "strategy.add_execution(buy_highest_volume, ['T', 'F', 'GM', 'PFE'])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "74e16f6c",
   "metadata": {},
   "source": [
    "To limit the number of long positions that can be held at any time to ```1```, we set [max_long_positions](https://www.pybroker.com/en/latest/reference/pybroker.config.html#pybroker.config.StrategyConfig.max_long_positions) to ```1``` in the [StrategyConfig](https://www.pybroker.com/en/latest/reference/pybroker.config.html#pybroker.config.StrategyConfig). In this example, we add the ```buy_highest_volume``` function to the [Strategy](https://www.pybroker.com/en/latest/reference/pybroker.strategy.html#pybroker.strategy.Strategy) object and specify the ticker symbols to trade: ```['T', 'F', 'GM', 'PFE']```."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "42807c79",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Backtesting: 2021-06-01 00:00:00 to 2022-06-01 00:00:00\n",
      "\n",
      "Loading bar data...\n",
      "[*********************100%***********************]  4 of 4 completed\n",
      "Loaded bar data: 0:00:00 \n",
      "\n",
      "Test split: 2021-06-01 00:00:00 to 2022-05-31 00:00:00\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100% (253 of 253) |######################| Elapsed Time: 0:00:00 Time:  0:00:00\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Finished backtest: 0:00:02\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>type</th>\n",
       "      <th>symbol</th>\n",
       "      <th>entry_date</th>\n",
       "      <th>exit_date</th>\n",
       "      <th>entry</th>\n",
       "      <th>exit</th>\n",
       "      <th>shares</th>\n",
       "      <th>pnl</th>\n",
       "      <th>return_pct</th>\n",
       "      <th>agg_pnl</th>\n",
       "      <th>bars</th>\n",
       "      <th>pnl_per_bar</th>\n",
       "      <th>stop</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>id</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>long</td>\n",
       "      <td>F</td>\n",
       "      <td>2021-06-02</td>\n",
       "      <td>2021-06-04</td>\n",
       "      <td>14.85</td>\n",
       "      <td>16.13</td>\n",
       "      <td>6734</td>\n",
       "      <td>8619.52</td>\n",
       "      <td>8.62</td>\n",
       "      <td>8619.52</td>\n",
       "      <td>2</td>\n",
       "      <td>4309.76</td>\n",
       "      <td>bar</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>long</td>\n",
       "      <td>F</td>\n",
       "      <td>2021-06-07</td>\n",
       "      <td>2021-06-09</td>\n",
       "      <td>15.93</td>\n",
       "      <td>15.51</td>\n",
       "      <td>6801</td>\n",
       "      <td>-2856.42</td>\n",
       "      <td>-2.64</td>\n",
       "      <td>5763.10</td>\n",
       "      <td>2</td>\n",
       "      <td>-1428.21</td>\n",
       "      <td>bar</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>long</td>\n",
       "      <td>F</td>\n",
       "      <td>2021-06-10</td>\n",
       "      <td>2021-06-14</td>\n",
       "      <td>15.43</td>\n",
       "      <td>15.06</td>\n",
       "      <td>6832</td>\n",
       "      <td>-2527.84</td>\n",
       "      <td>-2.40</td>\n",
       "      <td>3235.26</td>\n",
       "      <td>2</td>\n",
       "      <td>-1263.92</td>\n",
       "      <td>bar</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>long</td>\n",
       "      <td>F</td>\n",
       "      <td>2021-06-15</td>\n",
       "      <td>2021-06-17</td>\n",
       "      <td>14.96</td>\n",
       "      <td>14.99</td>\n",
       "      <td>6900</td>\n",
       "      <td>207.00</td>\n",
       "      <td>0.20</td>\n",
       "      <td>3442.26</td>\n",
       "      <td>2</td>\n",
       "      <td>103.50</td>\n",
       "      <td>bar</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>long</td>\n",
       "      <td>F</td>\n",
       "      <td>2021-06-18</td>\n",
       "      <td>2021-06-22</td>\n",
       "      <td>14.61</td>\n",
       "      <td>14.96</td>\n",
       "      <td>7003</td>\n",
       "      <td>2451.05</td>\n",
       "      <td>2.40</td>\n",
       "      <td>5893.31</td>\n",
       "      <td>2</td>\n",
       "      <td>1225.53</td>\n",
       "      <td>bar</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>80</th>\n",
       "      <td>long</td>\n",
       "      <td>F</td>\n",
       "      <td>2022-05-10</td>\n",
       "      <td>2022-05-12</td>\n",
       "      <td>13.43</td>\n",
       "      <td>12.47</td>\n",
       "      <td>7263</td>\n",
       "      <td>-6972.48</td>\n",
       "      <td>-7.15</td>\n",
       "      <td>-9423.13</td>\n",
       "      <td>2</td>\n",
       "      <td>-3486.24</td>\n",
       "      <td>bar</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>81</th>\n",
       "      <td>long</td>\n",
       "      <td>F</td>\n",
       "      <td>2022-05-13</td>\n",
       "      <td>2022-05-17</td>\n",
       "      <td>13.25</td>\n",
       "      <td>13.34</td>\n",
       "      <td>6835</td>\n",
       "      <td>615.15</td>\n",
       "      <td>0.68</td>\n",
       "      <td>-8807.98</td>\n",
       "      <td>2</td>\n",
       "      <td>307.58</td>\n",
       "      <td>bar</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>82</th>\n",
       "      <td>long</td>\n",
       "      <td>F</td>\n",
       "      <td>2022-05-18</td>\n",
       "      <td>2022-05-20</td>\n",
       "      <td>13.03</td>\n",
       "      <td>12.59</td>\n",
       "      <td>6739</td>\n",
       "      <td>-2965.16</td>\n",
       "      <td>-3.38</td>\n",
       "      <td>-11773.14</td>\n",
       "      <td>2</td>\n",
       "      <td>-1482.58</td>\n",
       "      <td>bar</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>83</th>\n",
       "      <td>long</td>\n",
       "      <td>F</td>\n",
       "      <td>2022-05-23</td>\n",
       "      <td>2022-05-25</td>\n",
       "      <td>12.72</td>\n",
       "      <td>12.57</td>\n",
       "      <td>6936</td>\n",
       "      <td>-1040.40</td>\n",
       "      <td>-1.18</td>\n",
       "      <td>-12813.54</td>\n",
       "      <td>2</td>\n",
       "      <td>-520.20</td>\n",
       "      <td>bar</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>84</th>\n",
       "      <td>long</td>\n",
       "      <td>F</td>\n",
       "      <td>2022-05-26</td>\n",
       "      <td>2022-05-31</td>\n",
       "      <td>12.99</td>\n",
       "      <td>13.59</td>\n",
       "      <td>6711</td>\n",
       "      <td>4026.60</td>\n",
       "      <td>4.62</td>\n",
       "      <td>-8786.94</td>\n",
       "      <td>2</td>\n",
       "      <td>2013.30</td>\n",
       "      <td>bar</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>84 rows × 13 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "    type symbol entry_date  exit_date  entry   exit  shares      pnl  \\\n",
       "id                                                                     \n",
       "1   long      F 2021-06-02 2021-06-04  14.85  16.13    6734  8619.52   \n",
       "2   long      F 2021-06-07 2021-06-09  15.93  15.51    6801 -2856.42   \n",
       "3   long      F 2021-06-10 2021-06-14  15.43  15.06    6832 -2527.84   \n",
       "4   long      F 2021-06-15 2021-06-17  14.96  14.99    6900   207.00   \n",
       "5   long      F 2021-06-18 2021-06-22  14.61  14.96    7003  2451.05   \n",
       "..   ...    ...        ...        ...    ...    ...     ...      ...   \n",
       "80  long      F 2022-05-10 2022-05-12  13.43  12.47    7263 -6972.48   \n",
       "81  long      F 2022-05-13 2022-05-17  13.25  13.34    6835   615.15   \n",
       "82  long      F 2022-05-18 2022-05-20  13.03  12.59    6739 -2965.16   \n",
       "83  long      F 2022-05-23 2022-05-25  12.72  12.57    6936 -1040.40   \n",
       "84  long      F 2022-05-26 2022-05-31  12.99  13.59    6711  4026.60   \n",
       "\n",
       "    return_pct   agg_pnl  bars  pnl_per_bar stop  \n",
       "id                                                \n",
       "1         8.62   8619.52     2      4309.76  bar  \n",
       "2        -2.64   5763.10     2     -1428.21  bar  \n",
       "3        -2.40   3235.26     2     -1263.92  bar  \n",
       "4         0.20   3442.26     2       103.50  bar  \n",
       "5         2.40   5893.31     2      1225.53  bar  \n",
       "..         ...       ...   ...          ...  ...  \n",
       "80       -7.15  -9423.13     2     -3486.24  bar  \n",
       "81        0.68  -8807.98     2       307.58  bar  \n",
       "82       -3.38 -11773.14     2     -1482.58  bar  \n",
       "83       -1.18 -12813.54     2      -520.20  bar  \n",
       "84        4.62  -8786.94     2      2013.30  bar  \n",
       "\n",
       "[84 rows x 13 columns]"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "result = strategy.backtest()\n",
    "result.trades"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4efd82ed",
   "metadata": {},
   "source": [
    "## Setting Position Sizes\n",
    "\n",
    "In **PyBroker**, you can set position sizes based on multiple tickers. To illustrate this, let's take a simple buy and hold strategy that starts trading after 100 days and holds positions for 30 days:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "57f222f0",
   "metadata": {},
   "outputs": [],
   "source": [
    "def buy_and_hold(ctx):\n",
    "    if not ctx.long_pos() and ctx.bars >= 100:\n",
    "        ctx.buy_shares = 100\n",
    "        ctx.hold_bars = 30\n",
    "        \n",
    "strategy = Strategy(YFinance(), '6/1/2021', '6/1/2022')\n",
    "strategy.add_execution(buy_and_hold, ['T', 'F', 'GM', 'PFE'])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "df3aa07c",
   "metadata": {},
   "source": [
    "This will buy ```100``` shares in each of ```['T', 'F', 'GM', 'PFE']```. But what if you don't want to use equal position sizing? For example, you may want to size positions so that more shares are allocated to tickers with lower volatility to decrease the portfolio's overall volatility.\n",
    "\n",
    "To customize position sizing for each ticker, we can define a [pos_size_handler](https://www.pybroker.com/en/latest/reference/pybroker.strategy.html#pybroker.strategy.Strategy.set_pos_size_handler) function that calculates the position size for each ticker:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "778f26f7",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "\n",
    "def pos_size_handler(ctx):\n",
    "    # Fetch all buy signals.\n",
    "    signals = tuple(ctx.signals(\"buy\"))\n",
    "    # Return if there are no buy signals (i.e. there are only sell signals).\n",
    "    if not signals:\n",
    "        return\n",
    "    # Calculates the inverse volatility, where volatility is defined as the\n",
    "    # standard deviation of close prices for the last 100 days.\n",
    "    get_inverse_volatility = lambda signal: 1 / np.std(signal.bar_data.close[-100:])\n",
    "    # Sums the inverse volatilities for all of the buy signals.\n",
    "    total_inverse_volatility = sum(map(get_inverse_volatility, signals))\n",
    "    for signal in signals:\n",
    "        size = get_inverse_volatility(signal) / total_inverse_volatility\n",
    "        # Calculate the number of shares given the latest close price.\n",
    "        shares = ctx.calc_target_shares(size, signal.bar_data.close[-1], cash=95_000)\n",
    "        ctx.set_shares(signal, shares)\n",
    "        \n",
    "strategy.set_pos_size_handler(pos_size_handler)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9436c840",
   "metadata": {},
   "source": [
    "The handler runs on every bar that generates a buy or sell signal when [buy_shares](https://www.pybroker.com/en/latest/reference/pybroker.context.html#pybroker.context.ExecContext.buy_shares) or [sell_shares](https://www.pybroker.com/en/latest/reference/pybroker.context.html#pybroker.context.ExecContext.sell_shares) is set on the [ExecContext](https://www.pybroker.com/en/latest/reference/pybroker.context.html#pybroker.context.ExecContext):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "ce28c70f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Backtesting: 2021-06-01 00:00:00 to 2022-06-01 00:00:00\n",
      "\n",
      "Loaded cached bar data.\n",
      "\n",
      "Test split: 2021-06-01 00:00:00 to 2022-05-31 00:00:00\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100% (253 of 253) |######################| Elapsed Time: 0:00:00 Time:  0:00:00\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Finished backtest: 0:00:00\n"
     ]
    }
   ],
   "source": [
    "result = strategy.backtest()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "21e70c4d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>type</th>\n",
       "      <th>symbol</th>\n",
       "      <th>entry_date</th>\n",
       "      <th>exit_date</th>\n",
       "      <th>entry</th>\n",
       "      <th>exit</th>\n",
       "      <th>shares</th>\n",
       "      <th>pnl</th>\n",
       "      <th>return_pct</th>\n",
       "      <th>agg_pnl</th>\n",
       "      <th>bars</th>\n",
       "      <th>pnl_per_bar</th>\n",
       "      <th>stop</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>id</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>long</td>\n",
       "      <td>T</td>\n",
       "      <td>2021-10-21</td>\n",
       "      <td>2021-12-03</td>\n",
       "      <td>19.60</td>\n",
       "      <td>17.54</td>\n",
       "      <td>2248</td>\n",
       "      <td>-4630.88</td>\n",
       "      <td>-10.51</td>\n",
       "      <td>-4630.88</td>\n",
       "      <td>30</td>\n",
       "      <td>-154.36</td>\n",
       "      <td>bar</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>long</td>\n",
       "      <td>F</td>\n",
       "      <td>2021-10-21</td>\n",
       "      <td>2021-12-03</td>\n",
       "      <td>16.41</td>\n",
       "      <td>19.66</td>\n",
       "      <td>2028</td>\n",
       "      <td>6591.00</td>\n",
       "      <td>19.80</td>\n",
       "      <td>1960.12</td>\n",
       "      <td>30</td>\n",
       "      <td>219.70</td>\n",
       "      <td>bar</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>long</td>\n",
       "      <td>GM</td>\n",
       "      <td>2021-10-21</td>\n",
       "      <td>2021-12-03</td>\n",
       "      <td>58.20</td>\n",
       "      <td>60.28</td>\n",
       "      <td>129</td>\n",
       "      <td>268.32</td>\n",
       "      <td>3.57</td>\n",
       "      <td>2228.44</td>\n",
       "      <td>30</td>\n",
       "      <td>8.94</td>\n",
       "      <td>bar</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>long</td>\n",
       "      <td>PFE</td>\n",
       "      <td>2021-10-21</td>\n",
       "      <td>2021-12-03</td>\n",
       "      <td>42.76</td>\n",
       "      <td>53.75</td>\n",
       "      <td>235</td>\n",
       "      <td>2582.65</td>\n",
       "      <td>25.70</td>\n",
       "      <td>4811.09</td>\n",
       "      <td>30</td>\n",
       "      <td>86.09</td>\n",
       "      <td>bar</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>long</td>\n",
       "      <td>T</td>\n",
       "      <td>2021-12-06</td>\n",
       "      <td>2022-01-19</td>\n",
       "      <td>17.81</td>\n",
       "      <td>20.49</td>\n",
       "      <td>2665</td>\n",
       "      <td>7142.20</td>\n",
       "      <td>15.05</td>\n",
       "      <td>11953.29</td>\n",
       "      <td>30</td>\n",
       "      <td>238.07</td>\n",
       "      <td>bar</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>long</td>\n",
       "      <td>F</td>\n",
       "      <td>2021-12-06</td>\n",
       "      <td>2022-01-19</td>\n",
       "      <td>19.05</td>\n",
       "      <td>23.66</td>\n",
       "      <td>1075</td>\n",
       "      <td>4955.75</td>\n",
       "      <td>24.20</td>\n",
       "      <td>16909.04</td>\n",
       "      <td>30</td>\n",
       "      <td>165.19</td>\n",
       "      <td>bar</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>long</td>\n",
       "      <td>GM</td>\n",
       "      <td>2021-12-06</td>\n",
       "      <td>2022-01-19</td>\n",
       "      <td>59.72</td>\n",
       "      <td>57.99</td>\n",
       "      <td>209</td>\n",
       "      <td>-361.57</td>\n",
       "      <td>-2.90</td>\n",
       "      <td>16547.47</td>\n",
       "      <td>30</td>\n",
       "      <td>-12.05</td>\n",
       "      <td>bar</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>long</td>\n",
       "      <td>PFE</td>\n",
       "      <td>2021-12-06</td>\n",
       "      <td>2022-01-19</td>\n",
       "      <td>52.57</td>\n",
       "      <td>53.97</td>\n",
       "      <td>290</td>\n",
       "      <td>406.00</td>\n",
       "      <td>2.66</td>\n",
       "      <td>16953.47</td>\n",
       "      <td>30</td>\n",
       "      <td>13.53</td>\n",
       "      <td>bar</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>long</td>\n",
       "      <td>T</td>\n",
       "      <td>2022-01-20</td>\n",
       "      <td>2022-03-04</td>\n",
       "      <td>20.53</td>\n",
       "      <td>17.87</td>\n",
       "      <td>2625</td>\n",
       "      <td>-6982.50</td>\n",
       "      <td>-12.96</td>\n",
       "      <td>9970.97</td>\n",
       "      <td>30</td>\n",
       "      <td>-232.75</td>\n",
       "      <td>bar</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>long</td>\n",
       "      <td>F</td>\n",
       "      <td>2022-01-20</td>\n",
       "      <td>2022-03-04</td>\n",
       "      <td>22.22</td>\n",
       "      <td>17.01</td>\n",
       "      <td>789</td>\n",
       "      <td>-4110.69</td>\n",
       "      <td>-23.45</td>\n",
       "      <td>5860.28</td>\n",
       "      <td>30</td>\n",
       "      <td>-137.02</td>\n",
       "      <td>bar</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>long</td>\n",
       "      <td>GM</td>\n",
       "      <td>2022-01-20</td>\n",
       "      <td>2022-03-04</td>\n",
       "      <td>55.88</td>\n",
       "      <td>43.08</td>\n",
       "      <td>255</td>\n",
       "      <td>-3264.00</td>\n",
       "      <td>-22.91</td>\n",
       "      <td>2596.28</td>\n",
       "      <td>30</td>\n",
       "      <td>-108.80</td>\n",
       "      <td>bar</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>long</td>\n",
       "      <td>PFE</td>\n",
       "      <td>2022-01-20</td>\n",
       "      <td>2022-03-04</td>\n",
       "      <td>53.80</td>\n",
       "      <td>48.09</td>\n",
       "      <td>192</td>\n",
       "      <td>-1096.32</td>\n",
       "      <td>-10.61</td>\n",
       "      <td>1499.96</td>\n",
       "      <td>30</td>\n",
       "      <td>-36.54</td>\n",
       "      <td>bar</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>long</td>\n",
       "      <td>T</td>\n",
       "      <td>2022-03-07</td>\n",
       "      <td>2022-04-19</td>\n",
       "      <td>17.88</td>\n",
       "      <td>19.51</td>\n",
       "      <td>3132</td>\n",
       "      <td>5105.16</td>\n",
       "      <td>9.12</td>\n",
       "      <td>6605.12</td>\n",
       "      <td>30</td>\n",
       "      <td>170.17</td>\n",
       "      <td>bar</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>long</td>\n",
       "      <td>F</td>\n",
       "      <td>2022-03-07</td>\n",
       "      <td>2022-04-19</td>\n",
       "      <td>16.43</td>\n",
       "      <td>15.98</td>\n",
       "      <td>1303</td>\n",
       "      <td>-586.35</td>\n",
       "      <td>-2.74</td>\n",
       "      <td>6018.77</td>\n",
       "      <td>30</td>\n",
       "      <td>-19.55</td>\n",
       "      <td>bar</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>long</td>\n",
       "      <td>GM</td>\n",
       "      <td>2022-03-07</td>\n",
       "      <td>2022-04-19</td>\n",
       "      <td>41.09</td>\n",
       "      <td>41.50</td>\n",
       "      <td>220</td>\n",
       "      <td>90.20</td>\n",
       "      <td>1.00</td>\n",
       "      <td>6108.97</td>\n",
       "      <td>30</td>\n",
       "      <td>3.01</td>\n",
       "      <td>bar</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16</th>\n",
       "      <td>long</td>\n",
       "      <td>PFE</td>\n",
       "      <td>2022-03-07</td>\n",
       "      <td>2022-04-19</td>\n",
       "      <td>48.18</td>\n",
       "      <td>50.62</td>\n",
       "      <td>200</td>\n",
       "      <td>488.00</td>\n",
       "      <td>5.06</td>\n",
       "      <td>6596.97</td>\n",
       "      <td>30</td>\n",
       "      <td>16.27</td>\n",
       "      <td>bar</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    type symbol entry_date  exit_date  entry   exit  shares      pnl  \\\n",
       "id                                                                     \n",
       "1   long      T 2021-10-21 2021-12-03  19.60  17.54    2248 -4630.88   \n",
       "2   long      F 2021-10-21 2021-12-03  16.41  19.66    2028  6591.00   \n",
       "3   long     GM 2021-10-21 2021-12-03  58.20  60.28     129   268.32   \n",
       "4   long    PFE 2021-10-21 2021-12-03  42.76  53.75     235  2582.65   \n",
       "5   long      T 2021-12-06 2022-01-19  17.81  20.49    2665  7142.20   \n",
       "6   long      F 2021-12-06 2022-01-19  19.05  23.66    1075  4955.75   \n",
       "7   long     GM 2021-12-06 2022-01-19  59.72  57.99     209  -361.57   \n",
       "8   long    PFE 2021-12-06 2022-01-19  52.57  53.97     290   406.00   \n",
       "9   long      T 2022-01-20 2022-03-04  20.53  17.87    2625 -6982.50   \n",
       "10  long      F 2022-01-20 2022-03-04  22.22  17.01     789 -4110.69   \n",
       "11  long     GM 2022-01-20 2022-03-04  55.88  43.08     255 -3264.00   \n",
       "12  long    PFE 2022-01-20 2022-03-04  53.80  48.09     192 -1096.32   \n",
       "13  long      T 2022-03-07 2022-04-19  17.88  19.51    3132  5105.16   \n",
       "14  long      F 2022-03-07 2022-04-19  16.43  15.98    1303  -586.35   \n",
       "15  long     GM 2022-03-07 2022-04-19  41.09  41.50     220    90.20   \n",
       "16  long    PFE 2022-03-07 2022-04-19  48.18  50.62     200   488.00   \n",
       "\n",
       "    return_pct   agg_pnl  bars  pnl_per_bar stop  \n",
       "id                                                \n",
       "1       -10.51  -4630.88    30      -154.36  bar  \n",
       "2        19.80   1960.12    30       219.70  bar  \n",
       "3         3.57   2228.44    30         8.94  bar  \n",
       "4        25.70   4811.09    30        86.09  bar  \n",
       "5        15.05  11953.29    30       238.07  bar  \n",
       "6        24.20  16909.04    30       165.19  bar  \n",
       "7        -2.90  16547.47    30       -12.05  bar  \n",
       "8         2.66  16953.47    30        13.53  bar  \n",
       "9       -12.96   9970.97    30      -232.75  bar  \n",
       "10      -23.45   5860.28    30      -137.02  bar  \n",
       "11      -22.91   2596.28    30      -108.80  bar  \n",
       "12      -10.61   1499.96    30       -36.54  bar  \n",
       "13        9.12   6605.12    30       170.17  bar  \n",
       "14       -2.74   6018.77    30       -19.55  bar  \n",
       "15        1.00   6108.97    30         3.01  bar  \n",
       "16        5.06   6596.97    30        16.27  bar  "
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "result.trades"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bfe968be",
   "metadata": {},
   "source": [
    "Using this method allows for a lot of possibilities, such as using [Mean-Variance Optimization](https://en.wikipedia.org/wiki/Modern_portfolio_theory) to determine portfolio allocations. \n",
    "\n",
    "[In the next notebook, we will discuss how to implement custom indicators in PyBroker](https://www.pybroker.com/en/latest/notebooks/5.%20Writing%20Indicators.html)."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.16"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
